import time
import urllib

from django.db import connection, transaction
from django.http import HttpResponseRedirect, StreamingHttpResponse
from django.shortcuts import render
from django.urls import reverse

import numpy as np

from WebSite.models.AppModel import Description, PredictList
from WebSite.views.app.predict import predict

from WebSite.views.auth import Auth
from WebSite.views.exceptions import AppException
from WebSite.views.utl import render_anonymous_page, required_json, GetJsonResponse, auth_required


@render_anonymous_page
def index(request, context):
	return render(request, 'app/index.html', context)


@render_anonymous_page
def register(request, context):
	return render(request, 'app/register.html', context)


def logout(request):
	Auth.logout(request)
	return HttpResponseRedirect(reverse("index"))


@render_anonymous_page
def description_page(request, context):
	texts = Description.objects.all()
	items = []
	for text in texts:
		items.append({'col': text.col, 'col_cn': text.col_cn, 'col_abbr': text.col_abbr})
	context['items'] = items
	return render(request, 'app/description.html', context)


@render_anonymous_page
def history_page(request, context):
	user_id = Auth.userId(request)
	if user_id is None:
		return render(request, 'app/history.html', context)
	cursor = connection.cursor()
	cursor.execute('select data_id,result,args,create_dt from forecast where user_id=%s order  by data_id', [user_id])
	items = cursor.fetchall()
	datas = []
	for item in items:
		result = '破产' if int(item[1]) == 1 else '非破产'
		datas.append({'data_id': item[0], 'result': result, 'args': item[2], 'create_dt': item[3]})
	context['data'] = datas
	return render(request, 'app/history.html', context)


def history_data(request):
	user_id = Auth.userId(request)
	if user_id is None:
		return GetJsonResponse({'error': '未登录'})
	data_id = request.GET.get('data_id', None)
	if data_id is None:
		return GetJsonResponse({'error': '缺少ID'})

	cursor = connection.cursor()
	cursor.execute('select * from forecast where  user_id=%s and data_id=%s', [user_id, data_id])
	items = cursor.fetchall()
	data = []
	for item in items:
		data.append(item[2:])

	response = StreamingHttpResponse(' '.join([str(item) for item in data[0]]))
	response['Content-Type'] = 'application/octet-stream'
	response['Content-Disposition'] = 'attachment;filename="{0}"'.format(urllib.parse.quote_plus('download.txt'))
	return response


@render_anonymous_page
def guide(request, context):
	return render(request, 'app/guide.html', context)


@render_anonymous_page
def predict_page(request, context):
	predicts = PredictList.objects.all()
	predict_list = []
	for single in predicts:
		predict_list.append({'id': single.predict_id, 'title': single.predict_name, 'summary': single.predict_summary,
		                     'url': single.predict_url})
	context['predict_list'] = predict_list
	return render(request, 'app/predict/predict.html', context)


@render_anonymous_page
def svm_page(request, context):
	descriptions = Description.objects.all()
	arrs = []
	for i in range(0, 30, 2):
		arrs.append({'x1': descriptions[i].col, 'cn1': descriptions[i].col_cn, 'x2': descriptions[i + 1].col,
		             'cn2': descriptions[i + 1].col_cn})
	context['arrs'] = arrs
	return render(request, 'app/predict/svm.html', context)


@auth_required
def type_predict(request, context, predict_type):
	descriptions = Description.objects.all()
	arrs = []
	for i in range(0, 30, 2):
		arrs.append({'x1': descriptions[i].col, 'cn1': descriptions[i].col_cn, 'x2': descriptions[i + 1].col,
		             'cn2': descriptions[i + 1].col_cn})
	context['arrs'] = arrs
	return render(request, 'app/predict/' + predict_type + '.html', context)


@required_json
def submit_predict(request):
	nums = request.POST.get('nums', None)
	if nums is None:
		raise AppException("缺少数据")

	args = request.POST.get('args', None)
	if args is None:
		raise AppException("缺少参数")

	predict_data = [np.asarray([float(item) for item in nums.split(',')])]

	cursor = connection.cursor()
	cursor.execute('select * from expert order by data_id')
	items = cursor.fetchall()
	result = []
	data = []
	for item in items:
		result.append(item[1])
		data.append(item[2:])
	expert_data = {'result': np.asarray(result), 'data': np.asarray(data)}
	final_result = predict(args, expert_data, predict_data)

	predict_result = '破产' if final_result[0] == 1 else '非破产'
	user_id = 0 if Auth.userId(request) is None else Auth.userId(request)
	save_data(user_id, final_result[0], args, predict_data[0])

	return GetJsonResponse({'result': 'OK', 'final_result': predict_result})


def save_data(user_id, result, args, data):
	with transaction.atomic():
		cursor = connection.cursor()
		cursor.execute('''insert into forecast
 								(user_id,result,args,create_dt,
 								X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,
 								X11,X12,X13,X14,X15,X16,X17,X18,X19,X20,
 								X21,X22,X23,X24,X25,X26,X27,X28,X29,X30)
 								values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,
 									   %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,
 									   %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,
 									   %s,%s,%s,%s)''',
		               [user_id, result, args, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), data[0],
		                data[1], data[2], data[3], data[4], data[5], data[6], data[7],
		                data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], data[16],
		                data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25],
		                data[26], data[27], data[28], data[29]])


@auth_required
def neural_page(request, context):
	descriptions = Description.objects.all()
	arrs = []
	for i in range(0, 30, 2):
		arrs.append({'x1': descriptions[i].col, 'cn1': descriptions[i].col_cn, 'x2': descriptions[i + 1].col,
		             'cn2': descriptions[i + 1].col_cn})
	context['arrs'] = arrs
	return render(request, 'app/predict/neural.html', context)


@auth_required
def ensemble_page(request, context):
	descriptions = Description.objects.all()
	arrs = []
	for i in range(0, 30, 2):
		arrs.append({'x1': descriptions[i].col, 'cn1': descriptions[i].col_cn, 'x2': descriptions[i + 1].col,
		             'cn2': descriptions[i + 1].col_cn})
	context['arrs'] = arrs
	return render(request, 'app/predict/ensemble.html', context)


@auth_required
def knn_page(request, context):
	descriptions = Description.objects.all()
	arrs = []
	for i in range(0, 30, 2):
		arrs.append({'x1': descriptions[i].col, 'cn1': descriptions[i].col_cn, 'x2': descriptions[i + 1].col,
		             'cn2': descriptions[i + 1].col_cn})
	context['arrs'] = arrs
	return render(request, 'app/predict/knn.html', context)
